package com.heiye.auth.strategy.impl;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Preconditions;
import com.heiye.auth.constant.RedisKeyConstants;
import com.heiye.auth.enums.ResponseCodeEnum;
import com.heiye.auth.model.dto.user.UserLoginRspDTO;
import com.heiye.auth.rpc.UserRpcService;
import com.heiye.auth.strategy.LoginStrategy;
import com.heiye.framework.common.exception.BizException;
import com.heiye.user.api.dto.resp.RegisterUserRspDTO;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Objects;

/**
 * @author: heiye
 * @date: 2025/02/23 下午8:05
 * @version: v1.0.0
 * @description: 手机登录
 */
@Slf4j
@Component
public class PhoneLoginStrategy implements LoginStrategy {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    @Resource
    private UserRpcService userRpcService;

    @Override
    public RegisterUserRspDTO login(String identifier, String credential, Integer type) {
        log.info("手机验证码登录 ==== 标识： {}", identifier);

        // 校验入参验证码是否为空
        Preconditions.checkArgument(StringUtils.isNotBlank(credential), "验证码不能为空");

        // 构建验证码 Redis Key
        String key = RedisKeyConstants.buildPhoneVerificationCodeKey(identifier);

        // 获取redis里对应手机号的验证码
        String sendCode = (String) redisTemplate.opsForValue().get(key);

        // 判断用户输入的验证码与 redis 里的验证码是否一致
        if (!StringUtils.equals(credential, sendCode)) {
            throw new BizException(ResponseCodeEnum.VERIFICATION_CODE_ERROR);
        }

        // RPC: 调用用户服务，注册用户
        RegisterUserRspDTO registerUserRspDTO = userRpcService.register(identifier, type);

        log.info("==> Auth registerUserRspDTO: {}", JSONUtil.toJsonStr(registerUserRspDTO));

        // 若调用用户服务，返回的用户数据为空，则提示登录失败
        Preconditions.checkArgument(Objects.nonNull(registerUserRspDTO), ResponseCodeEnum.LOGIN_FAIL);

        return registerUserRspDTO;
    }
}
